package com.generic.mybatis.dal.dao.impl;

import com.generic.mybatis.dal.dao.DaoRegistry;
import com.generic.mybatis.dal.dao.GenericDao;
import com.generic.mybatis.dal.util.Reflections;
import com.google.common.collect.Maps;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects;

/**
 * @author wuaj
 */
@Component
public class DaoRegistryImpl implements DaoRegistry, BeanPostProcessor {

    private Map<Class, GenericDao> daoMap = Maps.newHashMap();

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof GenericDao) {
            Type[] types = bean.getClass().getGenericInterfaces();
            if (types != null && types.length > 0) {
                // 从MapperProxy中获取父类接口，也就是被代理类Dao
                Class clazz = (Class) bean.getClass().getGenericInterfaces()[0];
                // 以Dao接口类的泛型作为Key,保存Dao到内存中
                daoMap.put(Reflections.getInterfaceGenericType(clazz, 0), (GenericDao) bean);
            }
        }
        return bean;
    }

    @Override
    public <T extends GenericDao> T getDao(Class clazz) {
        GenericDao dao = daoMap.get(clazz);
        return (T) Objects.requireNonNull(dao, clazz.getSimpleName() + " dao is null");
    }

}